﻿using LtccApi.Models;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace LtccApi.Controllers
{
    /// <summary>
    /// 验证码
    /// </summary>
    [Route("api/[Controller]")]
    [ApiController]
    public class CheckCodeController : Controller
    {
        private LtccContext mLtccContext;
        private HttpClient mHttpClient;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ltccContex"></param>
        public CheckCodeController(LtccContext ltccContex)
        {
            mLtccContext = ltccContex;
            mHttpClient = new HttpClient(new System.Net.Http.HttpClientHandler());
        }

        /// <summary>
        /// 验证码处理
        /// </summary>
        /// <returns></returns>
        [HttpGet("{tel}")]
        public IActionResult List(string tel)
        {
            List<string> listData = new List<string>();
            //异常参数处理
            if (tel == "" || tel.Length != 11)
            {
                return Ok(listData);
            }

            User user = new User();
            user.CheckCode = GenerateNum(tel,6);
            user.Phone = tel;
            Task<IActionResult> result = Edit(user);

            string url = string.Format("http://v.juhe.cn/sms/send?mobile={0}&tpl_id={1}&tpl_value={2}&key={3}", tel, 24327, HttpUtility.UrlEncode("#code#=" + user.CheckCode, Encoding.UTF8), "720dc2b061fc3988fd80172e373bdf0f");
            mHttpClient.GetAsync(url);
            if (result != null)
            {
                listData.Add("success");
                listData.ToList();
            }

            return Ok(listData);
        }

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<IActionResult> Edit(User user)
        {
            try
            {
                //异常判断
                if (user == null || !ModelState.IsValid)
                {
                    return null;
                }
                //查询用户
                var userinfo = mLtccContext.Users.Where(m=>m.Phone == user.Phone).SingleOrDefault();
                if (userinfo == null)  //用户为空则是注册账号
                {
                    User newUser = GenerateLtccUser(user.Phone, user.CheckCode);
                    mLtccContext.Users.Add(newUser);
                    mLtccContext.SaveChanges();
                    userinfo = mLtccContext.Users.Where(m => m.Phone == user.Phone).SingleOrDefault();
                }
                if(userinfo.DzUserID == 0)  //尚未到论坛注册
                {
                    //生成论坛用户
                    string userName = "app_" + GenerateNum(user.Phone, 11);
                    string password = GenerateNum(user.Phone, 11);
                    Task<int> resultID = GenerateForumUser(userName, password);
                    resultID.Wait();
                    //生成成功则更新轮胎查查用户
                    if (resultID.Result > 0)
                    {
                        userinfo.DzUserID = resultID.Result;
                        userinfo.DzUser = userName;
                        mLtccContext.Users.Update(userinfo);
                        mLtccContext.SaveChanges();
                    }
                    else
                    {
                        Console.WriteLine("论坛注册失败");
                        return null;
                    }
                }
                //查询验证码是否存在
                var checkCode = mLtccContext.CheckCodes.Where(m => m.UserId == userinfo.ID).SingleOrDefault();
                //更新或插入数据
                if (checkCode == null)  //插入记录
                {
                    CheckCode newCheckCode = GenerateCheckCode(user.CheckCode,userinfo.ID);
                    //newCheckCode.Code = user.CheckCode;
                    //newCheckCode.UserId = userinfo.ID;
                    //newCheckCode.CurrentTime = DateTime.Now.ToString("yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
                    mLtccContext.CheckCodes.Add(newCheckCode);
                }
                else  //更新记录
                {

                    //根据当前时间和上次生成验证码的时间来决定是否更新数据
                    DateTime currentTime = DateTime.Now;
                    DateTime lastTime = DateTime.ParseExact(checkCode.CurrentTime, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
                    long value = (currentTime.Ticks - lastTime.Ticks) / 10000000;  //将时间转换为秒
                    if (value < 60)  //距离上次发送时间不足60秒
                    {
                        Console.WriteLine("有账号发送验证码次数异常:{0}", user.Phone);
                        return null;
                    }
                    //更新数据
                    checkCode.Code = user.CheckCode;
                    checkCode.UserId = userinfo.ID;
                    checkCode.CurrentTime = DateTime.Now.ToString("yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
                    //checkCode.ID = checkCode.ID;  //update根据主键来update,一定要标识，否则会变成插入
                    mLtccContext.CheckCodes.Update(checkCode);
                }
                mLtccContext.SaveChanges();
            }
            catch (Exception e)
            {
                Console.WriteLine("异常={0}", e);
                return null;
            }
            return NoContent();
        }

        ///// <summary>
        ///// 根据手机号和验证码生成新的用户
        ///// </summary>
        ///// <param name="phone">手机号</param>
        ///// <param name="checkCode">验证码</param>
        ///// <returns></returns>
        //private async Task<int> GenerateUser(string phone,string checkCode)
        //{
        //    string userName = "app_" + GenerateNum(phone, 11);
        //    string password = GenerateNum(phone, 11);
        //    string email = password + "@qq.com";
        //    //生成论坛用户
        //    int resultID = await GenerateForumUser(userName, password);
        //    return resultID;
        //    //resultID对应的错误值
        //    //define('UC_USER_CHECK_USERNAME_FAILED', -1);
        //    //define('UC_USER_USERNAME_BADWORD', -2);
        //    //define('UC_USER_USERNAME_EXISTS', -3);
        //    //define('UC_USER_EMAIL_FORMAT_ILLEGAL', -4);
        //    //define('UC_USER_EMAIL_ACCESS_ILLEGAL', -5);
        //    //define('UC_USER_EMAIL_EXISTS', -6);
        //}

        /// <summary>
        /// 生成论坛用户
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        private async Task<int> GenerateForumUser(string userName, string password)
        {
            Dictionary<string, string> keys = new Dictionary<string, string>();
            keys["username"] = userName;
            keys["password"] = password;
            keys["email"] = password + "@qq.com";
            string url = "http://api.lt.cc/user/reg_discuz";

            
            
            var json = JsonConvert.SerializeObject(keys);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            //http请求
            HttpResponseMessage response = null;
            response = await mHttpClient.PostAsync(url, content);
            var contentData = await response.Content.ReadAsStringAsync();

            //    //define('UC_USER_CHECK_USERNAME_FAILED', -1);
            //    //define('UC_USER_USERNAME_BADWORD', -2);
            //    //define('UC_USER_USERNAME_EXISTS', -3);
            //    //define('UC_USER_EMAIL_FORMAT_ILLEGAL', -4);
            //    //define('UC_USER_EMAIL_ACCESS_ILLEGAL', -5);
            //    //define('UC_USER_EMAIL_EXISTS', -6);
            return Convert.ToInt32(contentData);
        }

        /// <summary>
        /// 生成轮胎查查用户
        /// </summary>
        /// <param name="phone"></param>
        /// <param name="checkCode"></param>
        /// <returns></returns>
        private User GenerateLtccUser(string phone,string checkCode)
        {
            User user = new User();
            user.Phone = phone;
            user.NickName = "";
            user.LastTime = "";
            user.DzUser = "";
            user.DzUserID = 0;
            user.Token = "";
            user.CheckCode = checkCode;

            return user;
        }

        /// <summary>
        /// 生成验证码对象
        /// </summary>
        /// <param name="code"></param>
        /// <param name="userID"></param>
        /// <returns></returns>
        private CheckCode GenerateCheckCode(string code,int userID)
        {
            CheckCode checkCode = new CheckCode();
            checkCode.Code = code;
            checkCode.UserId = userID;
            checkCode.CurrentTime = DateTime.Now.ToString("yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);

            return checkCode;
        }

        /// <summary>
        /// 随机生成指定长度字符串
        /// </summary>
        /// <param name="tel"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        private string GenerateNum(string tel,int len)
        {
            //当前时间和手机号码后八位作为随机种子
            //string curTime = DateTime.Now.ToString("ddHHmmss", DateTimeFormatInfo.InvariantInfo);
            string curTime = DateTime.Now.Ticks.ToString().Substring(10);
            int randSeed = Convert.ToInt32(curTime);
            int iTel = 0;
            //防止手机号码转换数字异常
            try
            {
                tel = tel.Substring(3);
                iTel = Convert.ToInt32(tel);
            }
            catch(Exception)
            {
                Console.WriteLine("手机号码转换出了异常{0}", tel);
                iTel = 0;
            }
            //随机种子
            randSeed += iTel;
            Random random = new Random(randSeed);
            //生成随机数
            string checkCode = "";
            for(int i = 0;i < len; ++i)
            {
                int rand = random.Next() % 10;
                checkCode += rand.ToString();
            }
            return checkCode;
        }

    }
}
